using Grand.Domain.Catalog;
using Grand.Domain.Payments;
using Grand.Domain.Tax;
using Grand.Infrastructure.ModelBinding;
using Grand.Infrastructure.Models;
using Grand.Web.Admin.Models.Common;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.ComponentModel.DataAnnotations;

namespace Grand.Web.Admin.Models.Orders;

public class OrderModel : BaseEntityModel
{
    //identifiers
    [GrandResourceDisplayName("Admin.Orders.Fields.ID")]
    public override string Id { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.ID")]
    public int OrderNumber { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Code")]
    public string Code { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.OrderGuid")]
    public Guid OrderGuid { get; set; }

    //store
    [GrandResourceDisplayName("Admin.Orders.Fields.Store")]
    public string StoreName { get; set; }

    //customer info
    [GrandResourceDisplayName("Admin.Orders.Fields.Customer")]
    public string CustomerId { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Customer")]
    public string CustomerInfo { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.CustomerEmail")]
    public string CustomerEmail { get; set; }

    public string CustomerFullName { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.CustomerIP")]
    public string CustomerIp { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.CustomValues")]
    public Dictionary<string, object> CustomValues { get; set; } = new();

    [GrandResourceDisplayName("Admin.Orders.Fields.Affiliate")]
    public string AffiliateId { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Affiliate")]
    public string AffiliateName { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.SalesEmployee")]
    public string SalesEmployeeId { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.SalesEmployee")]
    public string SalesEmployeeName { get; set; }

    //Used discounts
    [GrandResourceDisplayName("Admin.Orders.Fields.UsedDiscounts")]
    public IList<UsedDiscountModel> UsedDiscounts { get; set; } = new List<UsedDiscountModel>();

    //totals
    public TaxDisplayType TaxDisplayType { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.OrderSubtotalInclTax")]
    public string OrderSubtotalInclTax { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.OrderSubtotalExclTax")]
    public string OrderSubtotalExclTax { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.OrderSubTotalDiscountInclTax")]
    public string OrderSubTotalDiscountInclTax { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.OrderSubTotalDiscountExclTax")]
    public string OrderSubTotalDiscountExclTax { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.OrderShippingInclTax")]
    public string OrderShippingInclTax { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.OrderShippingExclTax")]
    public string OrderShippingExclTax { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.PaymentMethodAdditionalFeeInclTax")]
    public string PaymentMethodAdditionalFeeInclTax { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.PaymentMethodAdditionalFeeExclTax")]
    public string PaymentMethodAdditionalFeeExclTax { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Tax")]
    public string Tax { get; set; }

    public IList<TaxRate> TaxRates { get; set; } = new List<TaxRate>();
    public bool DisplayTax { get; set; }
    public bool DisplayTaxRates { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.OrderTotalDiscount")]
    public string OrderTotalDiscount { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.RedeemedLoyaltyPoints")]
    public int RedeemedLoyaltyPoints { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.RedeemedLoyaltyPoints")]
    public string RedeemedLoyaltyPointsAmount { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.OrderTotal")]
    public string OrderTotal { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.RefundedAmount")]
    public string RefundedAmount { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.SuggestedRefundedAmount")]
    public string SuggestedRefundedAmount { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Profit")]
    public string Profit { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Currency")]
    public string CurrencyCode { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.CurrencyRate")]
    [UIHint("DoubleN4")]
    public double CurrencyRate { get; set; }

    //edit totals
    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.OrderSubtotal")]
    public double OrderSubtotalInclTaxValue { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.OrderSubtotal")]
    public double OrderSubtotalExclTaxValue { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.OrderSubTotalDiscount")]
    public double OrderSubTotalDiscountInclTaxValue { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.OrderSubTotalDiscount")]
    public double OrderSubTotalDiscountExclTaxValue { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.OrderShipping")]
    public double OrderShippingInclTaxValue { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.OrderShipping")]
    public double OrderShippingExclTaxValue { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.PaymentMethodAdditionalFee")]
    public double PaymentMethodAdditionalFeeInclTaxValue { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.PaymentMethodAdditionalFee")]
    public double PaymentMethodAdditionalFeeExclTaxValue { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.Tax")]
    public double TaxValue { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.TaxRates")]
    public string TaxRatesValue { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.OrderTotalDiscount")]
    public double OrderTotalDiscountValue { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.Edit.OrderTotal")]
    public double OrderTotalValue { get; set; }

    //order status
    [GrandResourceDisplayName("Admin.Orders.Fields.OrderStatus")]
    public string OrderStatus { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.OrderStatus")]
    public int OrderStatusId { get; set; }

    public IList<SelectListItem> OrderStatuses { get; set; } = new List<SelectListItem>();

    //payment info
    [GrandResourceDisplayName("Admin.Orders.Fields.PaymentStatus")]
    public string PaymentStatus { get; set; }

    public PaymentStatus PaymentStatusEnum { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.PaymentMethod")]
    public string PaymentMethod { get; set; }

    public string PaymentTransactionId { get; set; }

    //shipping info
    public bool IsShippable { get; set; }
    public bool PickUpInStore { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.PickupAddress")]
    public AddressModel PickupAddress { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.ShippingStatus")]
    public string ShippingStatus { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.ShippingAddress")]
    public AddressModel ShippingAddress { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.ShippingMethod")]
    public string ShippingMethod { get; set; }

    public string ShippingAdditionDescription { get; set; }
    public string ShippingAddressGoogleMapsUrl { get; set; }
    public bool CanAddNewShipments { get; set; }

    //billing info
    [GrandResourceDisplayName("Admin.Orders.Fields.BillingAddress")]
    public AddressModel BillingAddress { get; set; }

    [GrandResourceDisplayName("Admin.Orders.Fields.VatNumber")]
    public string VatNumber { get; set; }

    //gift vouchers
    public IList<GiftVoucher> GiftVouchers { get; set; } = new List<GiftVoucher>();

    //items
    public bool HasDownloadableProducts { get; set; }
    public IList<OrderItemModel> Items { get; set; } = new List<OrderItemModel>();

    //creation date
    [GrandResourceDisplayName("Admin.Orders.Fields.CreatedOn")]
    public DateTime CreatedOn { get; set; }

    //checkout attributes
    public string CheckoutAttributeInfo { get; set; }


    //order notes
    [GrandResourceDisplayName("Admin.Orders.OrderNotes.Fields.DisplayToCustomer")]
    public bool AddOrderNoteDisplayToCustomer { get; set; }

    [GrandResourceDisplayName("Admin.Orders.OrderNotes.Fields.Note")]

    public string AddOrderNoteMessage { get; set; }

    public bool AddOrderNoteHasDownload { get; set; }

    [GrandResourceDisplayName("Admin.Orders.OrderNotes.Fields.Download")]
    [UIHint("Download")]
    public string AddOrderNoteDownloadId { get; set; }

    //refund info
    [GrandResourceDisplayName("Admin.Orders.Fields.PartialRefund.AmountToRefund")]
    public double AmountToRefund { get; set; }

    public double MaxAmountToRefund { get; set; }
    public string PrimaryStoreCurrencyCode { get; set; }

    //workflow info
    public bool CanCancelOrder { get; set; }


    //order's tags
    [GrandResourceDisplayName("Admin.Orders.Fields.OrderTags")]
    public string OrderTags { get; set; }

    #region Nested Classes

    public class OrderItemModel : BaseEntityModel
    {
        public string ProductId { get; set; }
        public string ProductName { get; set; }
        public string VendorName { get; set; }
        public string Sku { get; set; }

        public string PictureThumbnailUrl { get; set; }

        public string UnitPriceInclTax { get; set; }
        public string UnitPriceExclTax { get; set; }
        public double UnitPriceInclTaxValue { get; set; }
        public double UnitPriceExclTaxValue { get; set; }

        public int Quantity { get; set; }
        public int OpenQty { get; set; }
        public int CancelQty { get; set; }
        public int ShipQty { get; set; }
        public int ReturnQty { get; set; }

        public string DiscountInclTax { get; set; }
        public string DiscountExclTax { get; set; }
        public double DiscountInclTaxValue { get; set; }
        public double DiscountExclTaxValue { get; set; }

        public string SubTotalInclTax { get; set; }
        public string SubTotalExclTax { get; set; }
        public double SubTotalInclTaxValue { get; set; }
        public double SubTotalExclTaxValue { get; set; }

        public string AttributeInfo { get; set; }
        public string RecurringInfo { get; set; }
        public string RentalInfo { get; set; }
        public IList<string> MerchandiseReturnIds { get; set; } = new List<string>();
        public IList<string> PurchasedGiftVoucherIds { get; set; } = new List<string>();

        public bool IsDownload { get; set; }
        public int DownloadCount { get; set; }
        public DownloadActivationType DownloadActivationType { get; set; }
        public bool IsDownloadActivated { get; set; }
        public Guid LicenseDownloadGuid { get; set; }

        public string Commission { get; set; }
        public double CommissionValue { get; set; }
    }

    public class TaxRate : BaseModel
    {
        public string Rate { get; set; }
        public string Value { get; set; }
    }

    public class GiftVoucher : BaseModel
    {
        [GrandResourceDisplayName("Admin.Orders.Fields.GiftVoucherInfo")]
        public string CouponCode { get; set; }

        public string Amount { get; set; }
    }

    public class OrderNote : BaseEntityModel
    {
        public string OrderId { get; set; }

        [GrandResourceDisplayName("Admin.Orders.OrderNotes.Fields.DisplayToCustomer")]
        public bool DisplayToCustomer { get; set; }

        [GrandResourceDisplayName("Admin.Orders.OrderNotes.Fields.Note")]
        public string Note { get; set; }

        [GrandResourceDisplayName("Admin.Orders.OrderNotes.Fields.Download")]
        public string DownloadId { get; set; }

        [GrandResourceDisplayName("Admin.Orders.OrderNotes.Fields.Download")]
        public Guid DownloadGuid { get; set; }

        [GrandResourceDisplayName("Admin.Orders.OrderNotes.Fields.CreatedOn")]
        public DateTime CreatedOn { get; set; }

        [GrandResourceDisplayName("Admin.Orders.OrderNotes.Fields.CreatedByCustomer")]
        public bool CreatedByCustomer { get; set; }
    }

    public class UploadLicenseModel : BaseModel
    {
        public string OrderId { get; set; }

        public string OrderItemId { get; set; }

        [UIHint("Download")] public string LicenseDownloadId { get; set; }
    }

    public class AddOrderProductModel : BaseModel
    {
        [GrandResourceDisplayName("Admin.Catalog.Products.List.SearchProductName")]
        public string SearchProductName { get; set; }

        [UIHint("Category")]
        [GrandResourceDisplayName("Admin.Catalog.Products.List.SearchCategory")]
        public string SearchCategoryId { get; set; }

        [GrandResourceDisplayName("Admin.Catalog.Products.List.Brand")]
        [UIHint("Brand")]
        public string SearchBrandId { get; set; }

        [GrandResourceDisplayName("Admin.Catalog.Products.List.SearchCollection")]
        [UIHint("Collection")]
        public string SearchCollectionId { get; set; }

        [GrandResourceDisplayName("Admin.Catalog.Products.List.SearchProductType")]
        public int SearchProductTypeId { get; set; }

        public IList<SelectListItem> AvailableCollections { get; set; }
        public IList<SelectListItem> AvailableProductTypes { get; set; } = new List<SelectListItem>();

        public string OrderId { get; set; }
        public int OrderNumber { get; set; }

        #region Nested classes

        public class ProductModel : BaseEntityModel
        {
            [GrandResourceDisplayName("Admin.Orders.Products.AddNew.Name")]

            public string Name { get; set; }

            [GrandResourceDisplayName("Admin.Orders.Products.AddNew.SKU")]

            public string Sku { get; set; }
        }

        public class ProductDetailsModel : BaseModel
        {
            public string ProductId { get; set; }

            public string OrderId { get; set; }
            public int OrderNumber { get; set; }

            public ProductType ProductType { get; set; }

            public string Name { get; set; }

            [GrandResourceDisplayName("Admin.Orders.Products.AddNew.UnitPriceInclTax")]
            public double UnitPriceInclTax { get; set; }

            [GrandResourceDisplayName("Admin.Orders.Products.AddNew.UnitPriceExclTax")]
            public double UnitPriceExclTax { get; set; }

            [GrandResourceDisplayName("Admin.Orders.Products.AddNew.Quantity")]
            public int Quantity { get; set; }

            [GrandResourceDisplayName("Admin.Orders.Products.AddNew.TaxRate")]
            public double TaxRate { get; set; }

            //product attributes
            public IList<ProductAttributeModel> ProductAttributes { get; set; } = new List<ProductAttributeModel>();

            //gift voucher info
            public GiftVoucherModel GiftVoucher { get; set; } = new();

            public List<string> Warnings { get; set; } = new();
        }

        public class ProductAttributeModel : BaseEntityModel
        {
            public string ProductAttributeId { get; set; }

            public string Name { get; set; }

            public string TextPrompt { get; set; }

            public bool IsRequired { get; set; }

            public AttributeControlType AttributeControlType { get; set; }

            public IList<ProductAttributeValueModel> Values { get; set; } = new List<ProductAttributeValueModel>();
        }

        public class ProductAttributeValueModel : BaseEntityModel
        {
            public string Name { get; set; }

            public bool IsPreSelected { get; set; }
        }


        public class GiftVoucherModel : BaseModel
        {
            public bool IsGiftVoucher { get; set; }

            [GrandResourceDisplayName("Admin.Orders.Products.GiftVoucher.RecipientName")]

            public string RecipientName { get; set; }

            [GrandResourceDisplayName("Admin.Orders.Products.GiftVoucher.RecipientEmail")]

            public string RecipientEmail { get; set; }

            [GrandResourceDisplayName("Admin.Orders.Products.GiftVoucher.SenderName")]

            public string SenderName { get; set; }

            [GrandResourceDisplayName("Admin.Orders.Products.GiftVoucher.SenderEmail")]

            public string SenderEmail { get; set; }

            [GrandResourceDisplayName("Admin.Orders.Products.GiftVoucher.Message")]

            public string Message { get; set; }

            public GiftVoucherType GiftVoucherType { get; set; }
        }

        #endregion
    }

    public class UsedDiscountModel : BaseModel
    {
        public string DiscountId { get; set; }
        public string DiscountName { get; set; }
    }

    #endregion
}